require "#{RAILS_ROOT}/app/classes/cat/cat_examinee"
require "#{RAILS_ROOT}/app/classes/cat/cat_item"
require "#{RAILS_ROOT}/app/classes/irt/irt_exam"

#* cat_exam.rb
#* Copyright (C) 2010  Embian Inc.
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or 
#  (at your option) any later version.
#  
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#  
#  You should have received a copy of the GNU General Public License
#  along with This program.  If not, see <http://www.gnu.org/licenses/>.
#  
#* Manages items, an examinee
#* Author: KyoungMo Yang(E-mail : mo@embian.com)
#* Modified: 2010-11-30
#* References: IRTItem, IRTExam
class CATExam < IRTExam

  #* Functionailities
  # * Constructs an instance of CATExam class.
  #* Parameters 
  # * [profile] : an instance of UserProfile class
  #* Return
  # * An instance of CATExam class
  #* Note
  # * N/A
  def initialize
    super([], [], 1)
    @item_map = {}
    @last_item = nil
  end
  
  #* Functionailities
  # * Adds response for the treated item
  #* Parameters 
  # * [item] : CATItem or CATItem#iid
  # * [answer] : examinee's answer about the treated item
  #* Return
  # * [response] : response(CATExam::MISSING_RESPONSE, CATExam::CORRECT_RESPONSE, CATExam::INCORRECT_RESPONSE)
  #* Note
  # * N/A
  def answer_to(item, answer)
    item_id = item
    if item_id.is_a? CATItem
      item_id = item.iid
    end
    
    cat_item = get_item(item_id)
    raise "The item(#{item_id}) is not included in this exam!!" unless cat_item
    
    # #constants for examinees' missing response  
    # MISSING_RESPONSE    = -1
    # #constants for examinees' correct response
    # CORRECT_RESPONSE    = 1
    # #constants for examinees' incorrect response
    # INCORRECT_RESPONSE  = 0
    
    #TODO : support politomous model
    response = MISSING_RESPONSE
    if answer
      response = (cat_item.answer == answer ? CORRECT_RESPONSE : INCORRECT_RESPONSE)
    end
    
    examinee.responses[cat_item.no-1] = response
    return response
  end
  
  #* Functionailities
  # * Adds item that handled in CAT
  #* Parameters 
  # * [irt_item] : an instance of IRTItem
  #* Return
  # * [irt_item] : added item. if occured error, return nil
  #* Note
  # * N/A
  def add_item(cat_item)
    raise "Invlaid Parameter : cat_item must be an instance of CATItem class" unless cat_item.is_a? CATItem
    if cat_item && cat_item.iid.to_i > 0
      @items << cat_item
      cat_item.no = number_of_items
      @item_map[cat_item.iid] = cat_item.no - 1
      return cat_item
    end
    
    return nil
  end
  
  #* Functionailities
  # * Sets examinee
  #* Parameters 
  # * [cat_examinee] : an instance of CATExaminee
  #* Return
  # * N/A
  #* Note
  # * N/A
  def examinee=(cat_examinee)
    raise "Invlaid Parameter : cat_examinee must be an instance of CATExaminee class" unless cat_examinee.is_a? CATExaminee
    @examinees[0] = cat_examinee
  end
  
  #* Functionailities
  # * Returns examinee
  #* Parameters 
  # * N/A
  #* Return
  # * [cat_examinee] : an instance of CATExaminee
  #* Note
  # * N/A
  def examinee
    return @examinees[0]
  end
  
  #* Functionailities
  # * Returns last item
  #* Parameters 
  # * [irt_item] : an instance of IRTItem
  #* Return
  # * [irt_item] : added item. if occured error, return nil
  #* Note
  # * N/A
  def last_item
    return @items.last
  end
  
  #* Functionailities
  # * Returns registered item if the given item's id is present in store.
  #* Parameters 
  # * [item_id] : item id
  #* Return
  # * [irt_item] : Returns registered item if the given id is present in store. Otherwise, returns nil.
  #* Note
  # * N/A
  def get_item(item_id)
    return @items[@item_map[item_id]]
  end
  
  #* Functionailities
  # * Returns true if the given obj is present in store.
  #* Parameters 
  # * [obj] : an instance of IRTItem or item's id
  #* Return
  # * [result] : Returns true if the given obj is present in store. Otherwise, returns false
  #* Note
  # * N/A
  def has_item?(obj)
    return false unless obj
    if obj.is_a? CATItem
      return @item_map.has_key?(obj.iid)
    end
    
    return @item_map.has_key?(obj)
  end
end